package com.naiterui.ehp.bs.b2c.product.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.bo.b2c.cms.MedicineBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bp.utils.date.DateUtil;
import com.naiterui.ehp.bs.b2c.product.entity.Medicine;
import com.naiterui.ehp.bs.b2c.product.entity.Product;
import com.naiterui.ehp.bs.b2c.product.repository.IMedicineRepository;
import com.naiterui.ehp.bs.b2c.product.repository.IPrescriptionPlatformProductRepository;
import com.naiterui.ehp.bs.b2c.product.repository.IProductRepository;
import com.naiterui.ehp.bs.b2c.product.service.IInnerMedicineService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class InnerMedicineServiceImpl implements IInnerMedicineService {

    private static final Logger LOGGER = LoggerFactory.getLogger(InnerMedicineServiceImpl.class);

    @Autowired
    private IMedicineRepository medicineRepository;
    @Autowired
    private IProductRepository productRepository;
    @Autowired
    private IPrescriptionPlatformProductRepository prescriptionPlatformProductRepository;

    private static final String SERIAL_NUMBER_REDIS_KEY = CommonConstant.REDIS_PRE_B2C + "product_serial_number";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrUpdate(String operator, MedicineBO medicineBo) {

        Supplier<Product> productSupplier = () -> {
            Product product = new Product();
            product.setNumber(this.generateProductNumber());
            //product.setNumber(medicineBo.getNumber());
            product.setCreatedAt(new Date());
            product.setCreatedBy(operator);
            return product;
        };

        //获取商品
        Product product = Optional.ofNullable(medicineBo.getProductId())
            .map(productId -> this.productRepository.get(productId))
            .orElseGet(productSupplier);

        Supplier<Medicine> medicineSupplier = () -> {
            Medicine medicine = new Medicine();
            //获取商品编码
            medicine.setNumber(product.getNumber());
            medicine.setCreatedAt(new Date());
            medicine.setCreatedBy(operator);
            return medicine;
        };

        Medicine medicine = Optional.ofNullable(medicineBo.getProductId())
            .map(productId -> this.medicineRepository.findByProductId(productId))
            .orElseGet(medicineSupplier);

        Optional.of(medicine).ifPresent(medicineConsumer -> {
            // 复制属性
            BeanUtil.copyProperties(medicineBo, medicine);
            medicineConsumer.setNumber(product.getNumber());
            medicineConsumer.setChangedAt(new Date());
            medicineConsumer.setChangedBy(operator);
        });

        Optional.of(product).ifPresent(productConsumer -> {
            BeanUtils.copyProperties(medicine, productConsumer, "id", "number");
            //药理分类ID
            productConsumer.setClassificationId(medicine.getPharmacologyClassificationId());
            productConsumer.setType(Product.TYPE_MEDICINE);
            Integer relationSku = product.getRelationSku();
            if (relationSku == null) {
                productConsumer.setRelationSku(0);
            }
            //资料完整
            if (StringUtils.isAllEmpty(medicine.getPinyin())) {
                productConsumer.setDataIntegrity(0);
            } else {
                productConsumer.setDataIntegrity(1);
            }
            productConsumer.setValid(1);
            productConsumer.setChangedAt(new Date());
            productConsumer.setChangedBy(operator);
        });

        if (product.getId() == null) {
            this.productRepository.save(product);
            medicine.setProductId(product.getId());
            this.medicineRepository.save(medicine);
        } else {
            this.productRepository.update(product);
            this.medicineRepository.update(medicine);
        }

        return product.getId();

    }

    @Override
    public List<MedicineBO> getByIds(Set<Long> pIdSet) {
        List<Medicine> list = this.medicineRepository.findAllByProductIdIn(pIdSet);
        return list.stream().map(m -> {
            MedicineBO medicineBO = new MedicineBO();
            BeanUtil.copyProperties(m, medicineBO);
            return medicineBO;
        }).collect(Collectors.toList());
    }

    /**
     * 生成商品编码
     *
     * @return
     */
    private String generateProductNumber() {
        // 生成规则：药品编码M开头 + 建码日期六位：年后两位+月份+日期（190520）+ 5位顺序码    举例：M19052000001
        StringBuilder number = new StringBuilder();
        number.append("M");
        number.append(DateUtil.formatDate(new Date(), "yyMMdd"));
        long serialNumber = RedisUtil.keyOps().incr(SERIAL_NUMBER_REDIS_KEY);
        number.append(String.format("%05d", serialNumber));
        LOGGER.debug("生成商品编码:{}", number);
        return number.toString();
    }
}
